package com.wsj.security.extend;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List;

import javax.sql.DataSource;

import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.UserDetailsService;
import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.acegisecurity.userdetails.jdbc.JdbcDaoImpl;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.object.MappingSqlQuery;

import com.wsj.security.IUserDetails;
import com.wsj.security.UserDetailsImpl;

public class CustomerDaoHibernate extends JdbcDaoImpl implements UserDetailsService ,UserDetails
{
	
	private UserDetails userDetails=null;
	  //通过用户名获取认证.
	  private String authoritiesByUsernameQuery;
	  //通过用户名查询.
	  private String usersByUsernameQuery;
	  
	  //角色前缀
	  private String rolePrefix = "";
	
	  //通过用户名,检测用户登陆
	  public static final String DEF_USERS_BY_USERNAME_QUERY = "SELECT top 1 u.user_id, u.company_id, u.email, u.password, u.enabled"
					+" from authorities_role r, authorities_user_role ur, user u where r.role_id = ur.role_id and ur.user_id = u.user_id" 
					+" and email = ?"
					+" ";
	  
	  //通过用户名查询用户名和资源 ,需要修改
	  public static final String DEF_AUTHORITIES_BY_USERNAME_QUERY ="select  rs.resource_name ,r.role_name from authorities_resource rs, authorities_resource_role rsr ,authorities_role r ,authorities_user_role ur ,authorities_user u"
                    +" where u.user_id = ur.user_id and ur.role_id = r.role_id and r.role_id = rsr.role_id and rsr.resource_id = rs.resource_id"
                    +" and u.email = ? ";
	      
	  
//	通过用户名加载用户
		protected MappingSqlQuery usersByNameMapping;
		
		//通过用户名,加载用户角色和资源
	  protected MappingSqlQuery rolesByUsernameMapping;
	  
	  //
	  private boolean usernameBasedPrimaryKey = true;
	  
	  
	    public CustomerDaoHibernate()
	    {
	    	usersByUsernameQuery = DEF_USERS_BY_USERNAME_QUERY;
	        authoritiesByUsernameQuery = DEF_AUTHORITIES_BY_USERNAME_QUERY;
	    }
	    
	  
	 protected void initMappingSqlQueries() 
	 {
	        this.usersByNameMapping = new UsersByUsernameMapping(getDataSource());
	        this.rolesByUsernameMapping = new AuthoritiesByUsernameMapping(getDataSource());
	  }


   

	 
	 public boolean isUsernameBasedPrimaryKey() {
		return usernameBasedPrimaryKey;
	}


	public void setUsernameBasedPrimaryKey(boolean usernameBasedPrimaryKey) {
		this.usernameBasedPrimaryKey = usernameBasedPrimaryKey;
	}


	public String getAuthoritiesByUsernameQuery() {
		return authoritiesByUsernameQuery;
	}


	public void setAuthoritiesByUsernameQuery(String authoritiesByUsernameQuery) {
		this.authoritiesByUsernameQuery = authoritiesByUsernameQuery;
	}


	public String getRolePrefix() {
		return rolePrefix;
	}


	public void setRolePrefix(String rolePrefix) {
		this.rolePrefix = rolePrefix;
	}


	public MappingSqlQuery getRolesByUsernameMapping() {
		return rolesByUsernameMapping;
	}


	public void setRolesByUsernameMapping(MappingSqlQuery rolesByUsernameMapping) {
		this.rolesByUsernameMapping = rolesByUsernameMapping;
	}


	//通过用户名,获取用户对象.
	  public IUserDetails loadUserByUsername(String username)throws UsernameNotFoundException, DataAccessException 
	  {
		      //检测用户是否登陆.
		      List users = usersByNameMapping.execute(username);
		      IUserDetails user=null;
			try {
				if (users.size() == 0) 
				  {
				      throw new UsernameNotFoundException("User not found");
				  }

				  user = (IUserDetails) users.get(0);

				  //通过用户名
				  List dbAuths = rolesByUsernameMapping.execute(user.getUsername());

				    addCustomAuthorities(user.getUsername(), dbAuths);

				    if (dbAuths.size() == 0) {
				        throw new UsernameNotFoundException("User has no GrantedAuthority");
				    }

				    GrantedAuthority[] arrayAuths = (GrantedAuthority[]) dbAuths.toArray(new GrantedAuthority[dbAuths.size()]);

				    user.setAuthorities(arrayAuths);

				    if (!usernameBasedPrimaryKey) {
				        user.setUsername(username);
				    }
				    
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			 this.userDetails=user;
			 
		    return user;
     }
	  
	 
    /**
     * 通过用户名查询用户对象
     */
    protected class UsersByUsernameMapping extends MappingSqlQuery {
        protected UsersByUsernameMapping(DataSource ds) {
            super(ds, usersByUsernameQuery);
            declareParameter(new SqlParameter(Types.VARCHAR));
            compile();
        }

        protected Object mapRow(ResultSet rs, int rownum)
            throws SQLException {
        	int user_id = rs.getInt(1);
        	int company_id = rs.getInt(2);
            String username = rs.getString(3);
            String password = rs.getString(4);
            //是否启用
            boolean enabled = rs.getBoolean(5);
            
            IUserDetails user = new UserDetailsImpl(username, password, enabled, true, true, true, new GrantedAuthority[] {new GrantedAuthorityImpl("HOLDER")});
            user.setUserId(user_id);
            user.setCompanyId(company_id);
            return user;
        }
        
        
}
    
    
    /**
     * 查询用户的权限
     */
    protected class AuthoritiesByUsernameMapping extends MappingSqlQuery {
        protected AuthoritiesByUsernameMapping(DataSource ds) {
            super(ds, authoritiesByUsernameQuery);
            declareParameter(new SqlParameter(Types.VARCHAR));
            compile();
        }

        protected Object mapRow(ResultSet rs, int rownum)
            throws SQLException {
            String roleName = rolePrefix + rs.getString(2);
            GrantedAuthorityImpl authority = new GrantedAuthorityImpl(roleName);

            return authority;
        }
    }


	public MappingSqlQuery getUsersByNameMapping() {
		return usersByNameMapping;
	}


	public void setUsersByNameMapping(MappingSqlQuery usersByNameMapping) {
		this.usersByNameMapping = usersByNameMapping;
	}


	public String getUsersByUsernameQuery() {
		return usersByUsernameQuery;
	}


	public void setUsersByUsernameQuery(String usersByUsernameQuery) {
		this.usersByUsernameQuery = usersByUsernameQuery;
	}


	public GrantedAuthority[] getAuthorities() {
		
		return this.getUserDetails().getAuthorities();
	}


	public String getPassword() 
	{
		return this.getUserDetails().getPassword();
	}


	public String getUsername() {
		
		return this.getUserDetails().getUsername();
	}


	public boolean isAccountNonExpired() {
		// TODO Auto-generated method stub
		return true;
	}


	public boolean isAccountNonLocked() {
		// TODO Auto-generated method stub
		return true;
	}


	public boolean isCredentialsNonExpired() {
		// TODO Auto-generated method stub
		return true;
	}


	public boolean isEnabled() {
		// TODO Auto-generated method stub
		return true;
	}


	public UserDetails getUserDetails() 
	{
		
		return userDetails;
	}


	public void setUserDetails(UserDetails userDetails) {
		this.userDetails = userDetails;
	}
}